const ApiResponse = require('../utils/response');

/**
 * 验证规则类
 */
class ValidationRule {
  constructor(field, label) {
    this.field = field;
    this.label = label || field;
    this.rules = [];
  }

  required(message) {
    this.rules.push({
      type: 'required',
      message: message || `${this.label}不能为空`
    });
    return this;
  }

  string(message) {
    this.rules.push({
      type: 'string',
      message: message || `${this.label}必须是字符串`
    });
    return this;
  }

  number(message) {
    this.rules.push({
      type: 'number',
      message: message || `${this.label}必须是数字`
    });
    return this;
  }

  integer(message) {
    this.rules.push({
      type: 'integer',
      message: message || `${this.label}必须是整数`
    });
    return this;
  }

  array(message) {
    this.rules.push({
      type: 'array',
      message: message || `${this.label}必须是数组`
    });
    return this;
  }

  email(message) {
    this.rules.push({
      type: 'email',
      message: message || `${this.label}必须是有效的邮箱地址`
    });
    return this;
  }

  min(value, message) {
    this.rules.push({
      type: 'min',
      value,
      message: message || `${this.label}最小值为 ${value}`
    });
    return this;
  }

  max(value, message) {
    this.rules.push({
      type: 'max',
      value,
      message: message || `${this.label}最大值为 ${value}`
    });
    return this;
  }

  minLength(length, message) {
    this.rules.push({
      type: 'minLength',
      length,
      message: message || `${this.label}最少 ${length} 个字符`
    });
    return this;
  }

  maxLength(length, message) {
    this.rules.push({
      type: 'maxLength',
      length,
      message: message || `${this.label}最多 ${length} 个字符`
    });
    return this;
  }

  pattern(regex, message) {
    this.rules.push({
      type: 'pattern',
      regex,
      message: message || `${this.label}格式不正确`
    });
    return this;
  }

  in(values, message) {
    this.rules.push({
      type: 'in',
      values,
      message: message || `${this.label}必须是以下值之一: ${values.join(', ')}`
    });
    return this;
  }

  custom(validator, message) {
    this.rules.push({
      type: 'custom',
      validator,
      message: message || `${this.label}验证失败`
    });
    return this;
  }
}

/**
 * 验证器类
 */
class Validator {
  constructor() {
    this.fields = [];
  }

  field(fieldName, label) {
    const rule = new ValidationRule(fieldName, label);
    this.fields.push(rule);
    return rule;
  }

  validate(data) {
    const errors = {};

    for (const fieldRule of this.fields) {
      const value = data[fieldRule.field];
      
      for (const rule of fieldRule.rules) {
        let isValid = true;
        let errorMessage = rule.message;

        switch (rule.type) {
          case 'required':
            isValid = value !== undefined && value !== null && value !== '';
            break;

          case 'string':
            isValid = typeof value === 'string' || value === undefined;
            break;

          case 'number':
            isValid = typeof value === 'number' || value === undefined;
            break;

          case 'integer':
            isValid = Number.isInteger(Number(value)) || value === undefined;
            break;

          case 'array':
            isValid = Array.isArray(value) || value === undefined;
            break;

          case 'email':
            if (value !== undefined) {
              const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
              isValid = emailRegex.test(value);
            }
            break;

          case 'min':
            if (value !== undefined) {
              isValid = Number(value) >= rule.value;
            }
            break;

          case 'max':
            if (value !== undefined) {
              isValid = Number(value) <= rule.value;
            }
            break;

          case 'minLength':
            if (value !== undefined) {
              isValid = String(value).length >= rule.length;
            }
            break;

          case 'maxLength':
            if (value !== undefined) {
              isValid = String(value).length <= rule.length;
            }
            break;

          case 'pattern':
            if (value !== undefined) {
              isValid = rule.regex.test(value);
            }
            break;

          case 'in':
            if (value !== undefined) {
              isValid = rule.values.includes(value);
            }
            break;

          case 'custom':
            if (value !== undefined) {
              isValid = rule.validator(value, data);
            }
            break;
        }

        if (!isValid) {
          if (!errors[fieldRule.field]) {
            errors[fieldRule.field] = [];
          }
          errors[fieldRule.field].push(errorMessage);
          break; // 一个字段出错后跳过后续规则
        }
      }
    }

    return {
      isValid: Object.keys(errors).length === 0,
      errors
    };
  }

  middleware() {
    return (req, res, next) => {
      const result = this.validate(req.body);
      
      if (!result.isValid) {
        return ApiResponse.validationFailed(res, result.errors);
      }
      
      next();
    };
  }
}

/**
 * 创建验证器的工厂函数
 */
const createValidator = (callback) => {
  const validator = new Validator();
  callback(validator);
  return validator.middleware();
};

module.exports = {
  Validator,
  createValidator,
  ValidationRule
};

